package com.glodon.paas.document.dao.mysql;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.glodon.paas.consts.StringConst;
import com.glodon.paas.document.constant.DocumentConstant;
import com.glodon.paas.document.dao.FileDao;
import com.glodon.paas.document.dao.domain.FileInfoEntity;
import com.glodon.paas.document.dao.mapper.FileInfoMapper;
import com.glodon.paas.util.DateUtil;

public class FileInfoDaoMysqlImpl implements FileDao {

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Override
    public String insert(FileInfoEntity entity) {
        assert entity.getId() != null : "FileInfoEntity.getId() is null";
        assert entity.getType() != null : "FileInfo.type is null";
        // insert
        if (entity.getCreateTime() == null) {
            entity.setCreateTime(DateUtil.getNow());
        }
        if (DocumentConstant.FILE_TYPE_FOLDER.intValue() == entity.getType()) {
            entity.setActiveRevision(1);
        }
        entity.setUpdateTime(entity.getCreateTime());
        fileInfoMapper.insertSelective(entity);
        return entity.getId();
    }

    @Override
    public FileInfoEntity get(String id) {
        return fileInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public int delete(String id) {
        return fileInfoMapper.deleteByPrimaryKey(id);
    }

    @Override
    public FileInfoEntity getFile(String fileId, Integer[] status, Integer[] types) {
        FileInfoEntity file = fileInfoMapper.selectByPrimaryKey(fileId);
        if (file == null || (status != null && !Arrays.asList(status).contains(file.getDeletedStatus()))
            || (types != null && Arrays.asList(types).contains(file.getType()))) {
            return null;
        }
        return file;
    }

    @Override
    public List<FileInfoEntity> getFiles(String parentId, String fullName, Integer[] status, Integer[] types) {
        String name = null;
        String extension = null;
        if (StringUtils.isNotEmpty(fullName)) {
            name = FilenameUtils.getBaseName(fullName);
            extension = FilenameUtils.getExtension(fullName).toLowerCase();
        }
        return fileInfoMapper.selectFiles(parentId, name, extension, status, types);
    }

    // @Override
    // public FileInfoEntity getRootDoc(String userId, String fullName) {
    // String name = FilenameUtils.getBaseName(fullName);
    // String extension = FilenameUtils.getExtension(fullName).toLowerCase();
    // List<FileInfoEntity> list = fileInfoMapper.selectByFullName(userId, "", FILE_TYPE_FILE, name, extension, new
    // Integer[]{FILE_STATUS_NORMAL}, 0, 2);
    // if(list.size()>1){
    // logger.warn("Duplicate rootfile:userId=" + userId + ",fullName="+fullName);
    // return list.get(0);
    // }
    //
    // if(list.size()>0){
    // return list.get(0);
    // }else{
    // return null;
    // }
    // }

    // @Override
    // public FileInfoEntity getDocByParentName(String parentId, String fullName) {
    // String name = FilenameUtils.getBaseName(fullName);
    // String extension = FilenameUtils.getExtension(fullName).toLowerCase();
    // List<FileInfoEntity> list = fileInfoMapper.selectByFullName(null, parentId, FILE_TYPE_FILE, name, extension,new
    // Integer[]{FILE_STATUS_NORMAL}, 0, 2);
    // if(list.size()>1){
    // logger.warn("Duplicate file:parentId=" + parentId + ",fullName="+fullName);
    // return list.get(0);
    // }
    // if(list.size()>0){
    // return list.get(0);
    // }else{
    // return null;
    // }
    // }

    // @Override
    // public FileInfoEntity getRootFolder(String ownerId, String folderName) {
    // List<FileInfoEntity> list = fileInfoMapper.selectByFullName(ownerId, "", FILE_TYPE_FOLDER, folderName,
    // EXTENSION_NULL,new Integer[]{FILE_STATUS_NORMAL}, 0, 2);
    // if(list.size() > 1){
    // logger.warn("Duplicate RootFolder:ownerId=" + ownerId + ",folderName="+folderName);
    // return list.get(0);
    // }
    // if(list.size()>0){
    // return list.get(0);
    // }else{
    // return null;
    // }
    // }

    // @Override
    // public FileInfoEntity getFolderByParentName(String parentId, String folderName) {
    // List<FileInfoEntity> list = fileInfoMapper.selectByFullName(null, parentId, FILE_TYPE_FOLDER, folderName,
    // EXTENSION_NULL,new Integer[]{FILE_STATUS_NORMAL}, 0, 2);
    // if(list.size()>1){
    // logger.warn("Duplicate Folder:parentId=" + parentId + ",folderName="+folderName);
    // return list.get(0);
    // }
    // if(list.size()>0){
    // return list.get(0);
    // }else{
    // return null;
    // }
    // }

    // @Override
    // public List<FileInfoEntity> getRootFiles(String ownerId) {
    // return fileInfoMapper.selectByParentId(ownerId, "", null, FILE_STATUS_NORMAL, 0, DEFAULT_COUNT);
    // }
    //
    // @Override
    // public List<FileInfoEntity> getSubFiles(String parentId) {
    // return fileInfoMapper.selectByParentId(null, parentId, null, FILE_STATUS_NORMAL, 0, DEFAULT_COUNT);
    // }

    // /**
    // * 包含删除的文件
    // */
    // @Override
    // public List<FileInfoEntity> getAllSubFiles(String parentId) {
    // return fileInfoMapper.selectByParentId(null, parentId, null, null, 0, DEFAULT_COUNT);
    // }

    @Override
    public void delFile(String id) {
        // int rt =
        fileInfoMapper.deleteByPrimaryKey(id);
    }

    // /**
    // * 获取用户主动删除的文件
    // */
    // @Override
    // public List<FileInfoEntity> getDeletedFiles(String ownerId) {
    // return fileInfoMapper.selectByOwnerId(ownerId, null, null, FILE_STATUS_RECYCLE, 0, DEFAULT_COUNT);
    // }

    // /**
    // * 获取用户主动删除的
    // */
    // @Override
    // public FileInfoEntity getDeletedFile(String userId, String fileId) {
    // FileInfoEntity file = fileInfoMapper.selectByPrimaryKey(fileId);
    // if(file != null && (file.getDeletedStatus().intValue() == FILE_STATUS_RECYCLE ||
    // file.getDeletedStatus().intValue() == FILE_STATUS_RECYCLE_CASCADE)){
    // return file;
    // }
    //
    // return null;
    // }

    @Override
    public long getUsedSpace(String ownerId) {
        Long size = fileInfoMapper.totalUsedSize(ownerId, false);
        if (size == null) {
            return 0;
        }
        return size;
    }

    @Override
    public void updateFileName(String id, String newName, String updator) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", id);
        param.put("name", newName);
        param.put("updator", updator);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public void updateShareType(String id, Integer type) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", id);
        param.put("shareType", type);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public String getParentId(String id) {
        FileInfoEntity f = fileInfoMapper.selectByPrimaryKey(id);
        if (f != null) {
            return f.getParentId();
        }
        return null;
    }

    // @Override
    // public String getFileOwner(String id) {
    // FileInfoEntity f = fileInfoMapper.selectByPrimaryKey(id);
    // if(f!=null){
    // return f.getOwnerId();
    // }
    // return null;
    // }

    @Override
    public void cleanByOwnerId(String ownerId) {
        fileInfoMapper.deleteAllByOwnerId(ownerId, null);
    }

    @Override
    public String getFileId(String parentId, String path, Integer[] status, Integer[] types) {
        FileInfoEntity f = null;
        String[] names = StringUtils.split(path, StringConst.SEPARATOR_SLASH);
        for (String name : names) {
            String baseName = FilenameUtils.getBaseName(name);
            String extension = FilenameUtils.getExtension(name);

            List<FileInfoEntity> list = fileInfoMapper.selectFiles(parentId, baseName, extension, status, types); // deletedStatus,startIndex,
                                                                                                                  // count
            if (list != null && list.size() > 0) {
                f = list.get(0);
                parentId = f.getId();
            } else {
                return null;
            }
        }
        return f.getId();
    }

    @Override
    public void refreshCount(String fileId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("parentId", fileId);
        param.put("deletedStatus", DocumentConstant.FILE_STATUS_NORMAL);
        int count = fileInfoMapper.count(param);
        updateCount(fileId, count);
    }

    @Override
    public void updateCount(String fileId, int count) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("count", count);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public int updateDataBagId(String fileId, String dataBagId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("dataBagId", dataBagId);
        return fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public int updateParent(String fileId, String parentId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("parentId", parentId);
        return fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public void updateSizeNumCount(String id, long size, int num, int count, Date updateTime) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", id);
        param.put("fileSize", size);
        param.put("activeRevision", num);
        param.put("count", count);
        param.put("updateTime", updateTime);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public void updateStatus(String fileId, Integer deleteStatus) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("deletedStatus", deleteStatus);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    // @Override
    // public List<FileInfoEntity> selectByComplex(
    // String ownerId,
    // String parentId,
    // Integer type,
    // Integer deletedStatus,
    // String orderProperty,
    // Integer orderType,
    // Integer startIndex,
    // Integer count
    // ) {
    // if(orderType == null){
    // orderType = 1;
    // }
    // Map<String,Object> param = new HashMap<String,Object>();
    // param.put("ownerId", ownerId);
    // param.put("parentId", parentId);
    // param.put("type", type);
    // param.put("deletedStatus", deletedStatus);
    // param.put("startIndex", startIndex);
    // param.put("count", count);
    //
    // if(orderProperty != null){
    // String orderStr = "order by type ";
    // String temp = null;
    // if(orderType.intValue() == DatabaseConst.ORDER_BY_DESC_INT){
    // temp = DatabaseConst.ORDER_BY_DESC;
    // }else{
    // temp = "";
    // }
    //
    // if("name".equals(orderProperty)){
    // orderStr += ", name " + temp;
    // }else if("extension".equals(orderProperty)){
    // orderStr += ", extension " + temp;
    // }else if("createTime".equals(orderProperty)){
    // orderStr += ", create_time " + temp;
    // }
    // param.put("orderStr", orderStr);
    // }
    //
    // return fileInfoMapper.selectByComplex(param);
    // }

    @Override
    public List<FileInfoEntity> getExpiredFiles(String ownerId, int nDays, int limited) {
        Date delDay = DateUtil.getDate(DateUtil.intDateSub(DateUtil.getIntToday(), nDays));
        return fileInfoMapper.selectExpiredFiles(ownerId, delDay, limited);
    }

    @Override
    public void updateUpdator(String fileId, String userId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("updator", userId);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public void updateLock(String fileId, String lockId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("id", fileId);
        param.put("lockId", lockId);
        fileInfoMapper.updateByPrimaryKeyMap(param);
    }

    @Override
    public List<FileInfoEntity> getDeletedFiles(String ownerId) {
        return fileInfoMapper.selectDeletedFiles(ownerId);
    }

    @Override
    public FileInfoEntity getFileWithFolderCount(String fileId) {
        return fileInfoMapper.selectFileWithFolderCount(fileId);
    }
    
    public void setFileInfoMapper(FileInfoMapper fileInfoMapper) {
        this.fileInfoMapper = fileInfoMapper;
    }
}
